1 /**
2  * Declared the majority of the interfaces for Devisualization.Window
3  * 
4  * Authors:
5  * 		Richard Andrew Cattermole
6  * 
7  * License:
8  * 		The MIT License (MIT)
9  *
10  *		Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
11  *  	
12  *		Permission is hereby granted, free of charge, to any person obtaining a copy
13  * 		of this software and associated documentation files (the "Software"), to deal
14  * 		in the Software without restriction, including without limitation the rights
15  * 		to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16  * 		copies of the Software, and to permit persons to whom the Software is
17  * 		furnished to do so, subject to the following conditions:
18  *  	
19  * 		The above copyright notice and this permission notice shall be included in all
20  * 		copies or substantial portions of the Software.
21  *  	
22  * 		THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * 		IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * 		FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25  * 		AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * 		LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27  * 		OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28  * 		SOFTWARE.
29  * 
30  * Examples:
31  * 		To create a window without an OpenGL context:
32  * 		---
33  * 	 Windowable window = new Window(800, 600, "My window!"w, 100, 100);
34  * 	 window.show();
35  * 	 Window.messageLoop();
36  * 		---
37  * 
38  * This runs the message loop after showing the window.
39  * Does nothing with events. Or show any content.
40  */
41 module devisualization.window.interfaces.window;
42 import devisualization.window.interfaces.eventable;
43 public import devisualization.window.interfaces.events;
44 import devisualization.window.interfaces.context;
45 
46 /**
47  * Arguments to create a window.
48  * Some may be optional.
49  * 
50  * A minimum width and height should be supplied.
51  * 
52  * See_Also:
53  *	  Windowable
54  */
55 struct WindowConfig {
56     /**
57      * Width of the window to create.
58      * Must be atleast 0 (px).
59      */
60     uint width;
61 
62     /**
63      * Height of the window to create.
64      * Must be atleast 0 (px).
65      */
66     uint height;
67 
68     /**
69      * The title of the window to create.
70      * Commonly a UTF-8 support should be available.
71      *     However if not ASCII will be used. Which is effectively a string.
72      *     Assume ASCII values are safe as a value.
73      * 
74      * Default:
75      *		"A DWC window"
76      */
77     wstring title = "A DWC window";
78 
79     /**
80      * The x position of the window to be created.
81      * It is possible that this is ignored by the implementation.
82      * 
83      * Default:
84      *         0 (px)
85      */
86     int x;
87 
88     /**
89      * The y position of the window to be created.
90      * It is possible that this is ignored by the implementation.
91      * 
92      * Default:
93      *         0 (px)
94      */
95     int y;
96 
97     /**
98      * Specifies the type of context to create. Validated by the window implementation.
99      *
100      * Default:
101      *         None
102      */
103     WindowContextType contextType;
104 
105     /**
106      * Forces width and height to be atleast 0 (px).
107      */
108     invariant() {
109         assert(width > 0, "Should a window really have a 0px width?");
110         assert(height > 0, "Should a window really have a 0px height?");
111     }
112 }
113 
114 /**
115  * A generic window interface.
116  * 
117  * Should be supportive of majority of windowing toolkits in existance.
118  * Is unaware of screens.
119  * 
120  * Implementation should support two constructors:
121  * ---
122  *  this(T...)(T config) { this(WindowConfig(config)); }
123  *  this(WindowConfig config);
124  * ---
125  * 
126  * Events_Mechanism:
127  * 		A window support a set number of events.
128  *		From those the event offer set functionality to manipulate them.
129  *
130  *  Adds a listener on an event
131  *	---
132  *		void addEventName(void delegate(T));
133  *		void addEventName(bool delegate(T));
134  *	---
135  *
136  *	Removes the provided listener
137  *	---
138  *		void removeEventName(bool delegate(T));
139  *		void removeEventName(void delegate(T));
140  *	---
141  *	
142  *	Counts how many listeners for an event
143  *	---
144  *		size_t countEventName();
145  *	---
146  *
147  *	Runs the event for all listeners with the given arguments
148  *	---
149  *		void eventName(T);
150  *	---
151  *
152  *	Clears all listeners for an event
153  *	---
154  *		void clearEventName();
155  *	---
156  *
157  *	Optionally will also support:
158  *	---
159  *		void eventName(T[1 .. $]);
160  *	---
161  *	Where T[0] is Windowable.
162  *	This will run the event and pass in as first argument this (Windowable).
163  *
164  * Events:
165  *	Upon the message loop drawing period this is called.<br/>
166  *  onDraw		=	Windowable
167  *
168  *  When the message loop is informed the window has moved, this is called.<br/>
169  *  onMove		=	Windowable, int x, int y
170  * 
171  * 	When the message loop is informed the window has resized, this is called.<br/>
172  * 	onResize	=	Windowable, uint newWidth, uint newHeight
173  * 
174  *  When the window has been requested to be closed from the user, this is called.<br/>
175  *  On this event Windowable.close must be called manually.<br/>
176  *  onClose		=	Windowable
177  */
178 interface Windowable {
179     import devisualization.image;
180 
181     //this(T...)(T config) { this(WindowConfig(config)); } 
182     //this(WindowConfig);
183     
184     static {
185         /**
186          * Continues iteration of the message loop.
187          * 
188          * This is expected functionality provided from the implementation.
189          */
190         void messageLoop();
191 
192         /**
193          * A single iteration of the message loop.
194          * 
195          * This is expected functionality provided from the implementation.
196          */
197         void messageLoopIteration();
198     }
199     
200 	/**
201 	 * Hides the window.
202 	 * 
203 	 * See_Also:
204 	 * 		hide
205 	 */
206     void show();
207 
208 	/**
209 	 * Shows the window.
210 	 * 
211 	 * See_Also:
212 	 * 		close
213 	 */
214 	void hide();
215 
216     /*
217      * Window
218      */
219 	 
220     mixin IEventing!("onDraw", Windowable);
221     mixin IEventing!("onMove", Windowable, int, int);
222     mixin IEventing!("onResize", Windowable, uint, uint);
223     mixin IEventing!("onClose", Windowable);
224 
225     /*
226      * Mouse 
227      */
228 
229     mixin IEventing!("onMouseDown", Windowable, MouseButtons, int, int);
230     mixin IEventing!("onMouseMove", Windowable, int, int);
231     mixin IEventing!("onMouseUp", Windowable, MouseButtons);
232     
233     /*
234      * Keyboard
235      * KeyModifiers is an or'd mask or modifiers upon the key
236      */
237 
238     mixin IEventing!("onKeyDown", Windowable, Keys, KeyModifiers);
239     mixin IEventing!("onKeyUp", Windowable, Keys, KeyModifiers);
240 
241     @property {
242 
243 		/**
244 		 * Sets the title text.
245 		 * 
246 		 * Params:
247 		 * 		text	=	The text to set the title of the window to
248 		 */
249         void title(string text);
250 
251 		/**
252 		 * Sets the title text.
253 		 * 
254 		 * Params:
255 		 * 		text	=	The text to set the title of the window to
256 		 */
257 		void title(dstring text);
258 
259 		/**
260 		 * Sets the title text.
261 		 * 
262 		 * Params:
263 		 * 		text	=	The text to set the title of the window to
264 		 */
265 		void title(wstring text);
266         
267 		/**
268 		 * Resize the window.
269 		 * 
270 		 * Does not animate.
271 		 * 
272 		 * Params:
273 		 * 		width	=	The width to set to
274 		 * 		height	=	The height to set to
275 		 */
276         void size(uint width, uint height);
277 
278 		/**
279 		 * Move the window to coordinate.
280 		 * 
281 		 * Coordinate system based upon Top left corner of screen.
282 		 * Does not support screens (could be moved outside main screen).
283 		 * Coordinates can be negative, but is dependent upon the OS.
284 		 * 
285 		 * Params:
286 		 * 		x	=	The x coordinate to move to
287 		 * 		y	=	The y coordinate to move to
288 		 */
289         void move(int x, int y);
290         
291 		/**
292 		 * Enable / disable resizing of the window.
293 		 * 
294 		 * Params:
295 		 * 		can	=	Is it possible to resize the window (default yes)
296 		 */
297         void canResize(bool can = true);
298 
299 		/**
300 		 * Go into/out fullscreen
301 		 * 
302 		 * Params:
303 		 * 		isFullscreen	=	Should be fullscreen (default yes)
304 		 */
305         void fullscreen(bool isFullscreen = true);
306 
307         /**
308          * Closes the window.
309          * The window cannot reopened once closed.
310 		 *
311          * See_Also:
312          * 		hide
313          */
314         void close();
315 
316 		/**
317 		 * Has the window been closed?
318 		 * 
319 		 * Returns:
320 		 * 		True if close has been called
321 		 * 
322 		 * See_Also:
323 		 * 		close
324 		 */
325         bool hasBeenClosed();
326 
327 		/**
328 		 * Gets the current context that the window has open or null for none.
329 		 * 
330 		 * Returns:
331 		 * 		A context that has a buffer that can be swapped and activated once created
332 		 */
333         IContext context();
334     }
335 
336 	/**
337      * Sets the icon for the window.
338      * Supports transparency.
339      * 
340      * Params:
341      *		image		=	The image (from Devisualization.Image).
342 	 */
343     void icon(Image image);
344 
345     /**
346      * Sets the icon for the window.
347      * Supports transparency.
348      * 
349      * Params:
350      *		width		=	The width of the icon
351      *      height		=	The height of the icon
352      *      data 	    =  	rgb data 0 .. 255, 3 bytes per pixel
353      *      transparent =	The given pixel (3 bytes like data) color to use as transparency
354      * 
355      * Deprecated:
356      * 		Superseded by using Devisualization.Image's Image, as argument instead.
357      */
358     deprecated("Use Devisualization.Image method instead")
359     void icon(ushort width, ushort height, ubyte[3][] data, ubyte[3]* transparent = null);
360 }
361 
362 class WindowNotCreatable : Exception {
363     @safe pure nothrow this(string file = __FILE__, size_t line = __LINE__, Throwable next = null) {
364         super("Window failed to be created.", file, line, next);
365     }
366     
367     @safe pure nothrow this(Throwable next, string file = __FILE__, size_t line = __LINE__) {
368         super("Window failed to be created.", file, line, next);
369     }
370 }